<template>
  <div class="form-sparepart">
    <div class="btn-group">
      <!-- start 添加按钮 -->
      <el-button
        class="add-sparepart-btn"
        type="text"
        size="medium"
        v-if="!isPaySuccess"
        @click="showPartWindow"
      >{{$t('common.base.addModule', {module:''})}}</el-button>
      <!-- end 添加按钮 -->

      <!-- start 从备件清单中添加按钮 -->
      <el-button
        type="text"
        size="medium"
        v-if="!isPaySuccess && sparepartList.length > 0"
        @click="openPartListDialog"
      >{{$t('common.form.preview.sparepart.btn1')}}</el-button>
      <!-- end 从备件清单中添加按钮 -->
    </div>

    <!-- start 备件列表 -->
    <el-table
      v-if="value.length"
      header-row-class-name="base-table-header-v3"
      row-class-name="base-table-row-v3"
      :data="tableValue"
      border>
      <el-table-column
        v-for="(column, index) in colums"
        :key="`${column.field}_${index}`"
        :label="column.label"
        :prop="column.field"
        show-overflow-tooltip
        :min-width="column.minWidth || '108px'"
      >
        <template slot-scope="scope">
          <!-- start 数量 -->
          <template v-if="column.field === 'number' && !isPaySuccess">
            <input class="sparepart-number-input" :disabled="isReplaceProductCard" type="number" v-model="scope.row.number" @change="handleSparepartNum(scope.row)" />
          </template>
          <!-- end 数量 -->

          <!-- start 单价 -->
          <template v-else-if="column.field === 'salePrice' && allowEditPrice">
            <input class="sparepart-number-input" type="number" v-model="scope.row.salePrice" @change="handlePrice(scope.row)" />
          </template>
          <!-- end 单价 -->

          <!-- start 小计 -->
          <template v-else-if="column.field === 'total'">
            {{ (scope.row.number * scope.row.salePrice).toFixed(2) }}
          </template>
          <!-- end 小计 -->

          <template v-else-if="column.formType === 'address'">
            {{formatCustomizeAddress(scope.row[column.field])}}
          </template>
          <template v-else-if="column.formType === 'select'">
            {{Array.isArray(scope.row[column.field]) ? scope.row[column.field].join(',') : scope.row[column.field]}}
          </template>
          <!-- start 仓库 -->
          <template v-else-if="column.field === 'repertoryName'">
            <template v-if="isOpenData && scope.row.repertoryStaffId">
              <open-data type='userName' :openid="scope.row.repertoryStaffId"></open-data>
            </template> 
            <template v-else>
              {{scope.row.repertoryName}}
            </template>
          </template>
          <!-- end 仓库 -->

          <!-- start 操作 -->
          <template v-else-if="column.field === 'action'">
            <el-button class="text-danger" type="text" size="mini" @click="deleteItem(scope)">{{$t('common.base.delete')}}
          </el-button></template>
          <!-- end 操作 -->

          <!-- start 安装产品id获取安装产品名称 -->
          <template v-else-if="column.field === 'installProductId'">
            {{ getProductName(scope.row[column.field]) }}
          </template>
          <!-- end  安装产品id获取安装产品名称 -->

          <template v-else>{{ scope.row[column.field] }}</template>
        </template>
      </el-table-column>
    </el-table>
    <!-- end 备件列表 -->
    <div v-if="isFreeSparePartFee" class="free-sparepart-fee"><i class="iconfont icon-warning-circle-fill"></i>{{$t('common.form.preview.sparepart.des1')}}</div>
    <!-- start 添加备件弹窗 -->
    <base-window :unique="false" :flicker="flickerWindow" size="medium" :top="true" :show.sync="visible" :title="$t('common.form.preview.sparepart.title1')" class-name="form-sparepart-modal" width="700px" @close="reset">
      <div class="base-modal-content">
        <template v-if="isReplaceProductCard">
          <h3 class="update-sparepart-title">{{$t('common.form.preview.sparepart.des2')}}</h3>
        </template>
        <form-builder ref="form" :fields="fields" :value="sparepart" @update="update">
          <!-- start 请选择产品 -->
          <template slot="product" slot-scope="{ field }" v-if="showRepertory">
            <form-item :label="field.displayName">
              <form-select :placeholder="field.placeholder" :field="field" :source="productsList" v-model="replaceProductId" @update="updateProduct" :clearable="false"/>
            </form-item>
          </template>
          <!-- end 请选择产品 -->

          <!-- start 请选择配件类别 -->
          <template slot="relationPartCard" slot-scope="{ field }" v-if="showRepertory">
            <form-item :label="field.displayName">
              <form-select :placeholder="field.placeholder" :field="field" :source="relationPartCards" v-model="replaceCardId" @update="updateRelationPartCard" :clearable="false"/>
            </form-item>
          </template>
          <!-- end 请选择配件类别 -->

          <!-- start 请选择配件 -->
          <template slot="cardInfo" slot-scope="{ field }" v-if="showRepertory">
            <div>
              <form-item :label="field.displayName">
                <form-select :placeholder="field.placeholder" :option-style="{height:'100%',background:'#fff'}" :field="field" :source="cardInfos" v-model="cardInfoId" @update="updateCardInfo" :clearable="false">
                  <template slot="option" slot-scope="slotProps">
                    <form-view :fields="cardInfoFields" :value="slotProps.option">
                      <template slot="part" slot-scope="{ field, value }">
                        <div class="form-view-row">
                          <label>{{ field.displayName }}</label>
                          <div class="form-view-row-content task-card-view-row">
                            {{ value[0].name }}
                          </div>
                        </div>
                      </template>
                    </form-view>
                    <div style="margin: 10px 0;width:100%;border-bottom:1px solid #ccc"></div>
                  </template>
                </form-select>
              </form-item>
              <template v-if="isReplaceProductCard">
                <h3 class="update-sparepart-mess">{{$t('common.form.preview.sparepart.des3')}}</h3>
              </template>
            </div>
          </template>
          <!-- end 请选择配件 -->

          <!-- start 仓库 -->
          <template slot="repertory" slot-scope="{ field }" v-if="showRepertory">
            <form-item :label="field.displayName">
              <form-select :field="field" :source="repertoryList" v-model="repertoryId" @update="updateRepertory" :clearable="false"/>
            </form-item>
          </template>
          <!-- end 仓库 -->

          <!-- start 安装产品 只有一个产品默认选中-->
          <template v-if="partField.length && products.length == 1">
            <template slot="installProductId" slot-scope="{ field }" >
              <form-item :label="field.displayName">
                <form-select :field="field" v-model="installProductId" />
              </form-item>
            </template>
          </template>
          
          <!-- end 安装产品 -->

          <!-- start 备件 -->
          <template slot="part" slot-scope="{ field }">
            <form-item :label="field.displayName">
              <biz-form-remote-select
                :input-disabled="sparepartDisabled"
                :field="field"
                v-model="selectedSparepart"
                :remote-method="searchPart"
                @input="updatePart"
                :placeholder="$t('common.placeholder.select')">
                <div class="sparepart-template-option" slot="option" slot-scope="{ option }">
                  <h3>{{ option.name }}</h3>
                  <p>
                    <span>
                      <label>{{$t('common.form.preview.sparepart.label1')}}</label>
                      <span>{{ option.serialNumber }}</span>
                    </span>
                    <span>
                      <label>{{$t('common.form.preview.sparepart.label2')}}</label>
                      <span>{{ option.type }}</span>
                    </span>
                    <span>
                      <label>{{$t('common.form.preview.sparepart.label3')}}</label>
                      <span>{{ option.standard }}</span>
                    </span>
                    <span>
                      <label>{{$t('common.form.preview.sparepart.label4')}}</label>
                      <span>{{ option.availableNum }} {{option.unit}}</span>
                    </span>
                  </p>
                  <p class="sparepart-addition-info">
                    <span>
                      <label>{{$t('common.form.preview.sparepart.label5')}}</label>
                      <span>{{ option.description }}</span>
                    </span>
                    <span v-if="initData.openSuperCodePro">
                      <label class="addition-product-type">{{$t('common.form.preview.sparepart.label6')}}</label>
                      <span>
                        {{
                          option.productTypeList &&
                            option.productTypeList.map(i => (i && i.catalogName) || '').join('，')
                        }}
                      </span>
                    </span>
                  </p>
                </div>
              </biz-form-remote-select>
            </form-item>
          </template>
          <!-- end 备件 -->

          <!-- start 数量 -->
          <template slot="number" slot-scope="{ field, value }">
            <form-item :label="field.displayName" :validation="validateNumber" class="goget-box">
              <form-number :field="field" :value="value" @update="update" />
              <span class="goget" v-if="isGoGet" @click="goGet">{{$t('common.form.preview.sparepart.btn2')}}</span>
            </form-item>
          </template>
          <!-- end 数量 -->

          <!-- start 小计 -->
          <template slot="total" slot-scope="{ field }">
            <form-item :label="field.displayName">
              <form-text :field="field" :value="total" />
            </form-item>
          </template>
          <!-- end 小计 -->
        </form-builder>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="cancelWindow">{{$t('common.base.cancel')}}</el-button>
        <el-button type="primary" @click="submit">{{$t('common.base.save')}}</el-button>
      </div>
    </base-window>
    <!-- end 添加备件弹窗 -->

    <!-- start 备件清单弹窗 -->
    <sparepart-list-dialog
      ref="sparepartListDialog"
      :value="value"
      :data="sparepartList"
      :fields="sparepartFields"
      :allow-part-out="allowPartOut"
      :personal-repertory="personalRepertory"
    />
    <!-- end 备件清单弹窗 -->
  </div>
</template>

<script>
import { isOpenData, openAccurateTab } from '@src/util/platform'
/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import { getCardFieldAll } from '@src/api/ProductV2Api';
/* components */
import SparepartListDialog from './components/SparepartListDialog';
/* mixin */
import FormMixin from '@src/component/form/mixin/form';

/* util */
import MathUtil from '@src/util/math';
import * as math from 'mathjs';
import _ from 'lodash';
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
import { objectDateToTimestamp, formatAddress } from 'pub-bbx-utils';
export default {
  name: 'form-sparepart',
  mixins: [FormMixin],
  inject: ['initData'],
  props: {
    field: {
      type: Object,
      default: () => ({})
    },
    value: {
      type: Array,
      default: () => ([])
    },
  },
  data() {
    return {
      isOpenData,
      partField: [],
      installProductId: '',
      products: this.initData?.task?.products || [],
      originValue: [],
      visible: false,
      showRepertory: true,
      repertoryId: 0, // 仓库ID
      repertoryList: [], // 仓库列表数据
      selectedSparepart: [], // 当前选中的备件
      sparepart: this._initData(), // 备件信息
      config: {}, // 备件配置
      editUnitPrice: false, // 是否可以修改单品价格
      isPaySuccess: false, // 是否支付成功
      sparepartCard: {}, // 备件清单附加组件
      sparepartList: [], // 备件清单
      // 窗口是否闪烁
      flickerWindow: false,
      isFreeSparePartFee: false,
      isGoGet:false,
      relationPartCards: [], // 配件类别列表
      cardInfos: [], // 配件列表
      replaceProductId: '',
      replaceCardId: '',
      cardInfoId: '',
      isReplaceProductCard: this.initData?.taskType?.options?.replaceProductCard, // 判断开启工单更换备件时是否替换产品中同型号配件
      cardInfoFields: [],
      cardInfoColums: [], // 保存后添加的备件表格列
      cardInfoColumsAll: [], // 添加多个备件保存的Fields
      searchValue: '', // 备件替换搜索keyWord
      replaceCardIds: [], // 保存已选择的替换备件类目，查找自定义字段
      replaceCardInfoIds: [], // 保存已选择的替换备件，查找自定义字段
    }
  },
  computed: {
    tableValue(){
      return this.value.map(item=>{
        // userAddData 是前端自己定义的标识，为 true 的话代表该数据是用户新建的。
        if(item.userAddData){
          item.oldNumberVal = 0
        }else if (!item.hasOwnProperty('oldNumberVal')) {
          item.oldNumberVal = item.number
        } 
        return Object.assign(item, item.cardInfoAttribute)
      })
    },
    cardInfoFilterFields(){
      let tempArr = this.cardInfoFields.filter(item=>{
        return item.formType != 'relationReplacementPart' && item.fieldName != 'part'
      })
      return tempArr
    },
    sparepartDisabled(){
      if(!this.isReplaceProductCard){
        return false
      }
      return !(this.cardInfoId)
    },
    productsList(){
      return this.products.map(item=>{
        return {
          text: item.name,
          value: item.id
        }
      })
    },
    /**
    * @description 备件列表项
    */
    colums() {
      let colums = [{
        label: this.$t('common.form.preview.sparepart.colum1'),
        field: 'name'
      }, {
        label: this.$t('common.form.preview.sparepart.colum2'),
        field: 'serialNumber'
      }, {
        label: this.$t('common.form.preview.sparepart.colum3'),
        field: 'type'
      }, {
        label: this.$t('common.form.preview.sparepart.colum4'),
        field: 'standard'
      }, {
        label: this.$t('common.form.preview.sparepart.colum5'),
        field: 'repertoryName'
      }, {
        label: this.$t('common.form.preview.sparepart.colum6'),
        field: 'number',
      }, {
        label: this.$t('common.form.preview.sparepart.colum7'),
        field: 'salePrice',
      }, {
        label: this.$t('common.form.preview.sparepart.colum8'),
        field: 'total',
      }]

      // 支付成功前可编辑
      if (!this.isPaySuccess) {
        colums.push({
          label: this.$t('common.base.operation'),
          field: 'action',
          minWidth: '70px'
        })
      }
      // 增加安装产品和安装位置
      this.partField.forEach((_part, _ind) => {
        colums.splice(_ind + 1, 0, {
          label: _part.displayName,
          field: _part.fieldName
        })
      })
      this.cardInfoColumsAll.forEach((_item, _ind)=>{
        colums.splice(-4, 0, {
          label: _item.displayName,
          formType: _item.formType,
          field: _item.fieldName
        })
      })

      // 完成回执-备件table 是否隐藏单价和小计
      if(!this.serviceProviderShowPrice) {
        colums = colums.filter(column => column.field !== 'salePrice' && column.field !== 'total')
      }

      return colums;
    },
    /**
    * @description 备件字段
    */
    fields() {
      // TODO-bdz 可能存在逻辑
      let fields = [{
        formType: 'select',
        fieldName: 'repertory',
        displayName: '仓库',
        placeholder: '请选择',
        isNull: 0
      }, {
        formType: 'select',
        fieldName: 'part',
        displayName: '备件',
        placeholder: '请选择',
        isNull: 0,
      }, {
        formType: 'text',
        fieldName: 'serialNumber',
        displayName: '编号',
        isNull: 1,
        disabled: true
      }, {
        formType: 'text',
        fieldName: 'type',
        displayName: '类别',
        isNull: 1,
        disabled: true
      }, {
        formType: 'text',
        fieldName: 'standard',
        displayName: '规格',
        isNull: 1,
        disabled: true
      }, {
        formType: 'text',
        fieldName: 'salePrice',
        displayName: '单价',
        isNull: 1,
        disabled: true
      }, {
        formType: 'textarea',
        fieldName: 'description',
        displayName: '说明',
        isNull: 1,
        disabled: true
      }, {
        formType: 'number',
        fieldName: 'repertoryCount',
        displayName: '库存',
        isNull: 1,
        disabled: true
      }, {
        formType: 'number',
        fieldName: 'number',
        displayName: '用量',
        isNull: 0,
      }, {
        formType: 'text',
        fieldName: 'total',
        displayName: '小计',
        isNull: 1,
        disabled: true
      }]

      let updateSparepartField = [
        {
          formType: 'select',
          fieldName: 'product',
          displayName: '产品',
          placeholder: '请选择产品',
          isNull: 0
        },
        {
          formType: 'select',
          fieldName: 'relationPartCard',
          displayName: '配件类别',
          placeholder: '请选择配件类别',
          isNull: 0
        },
        {
          formType: 'select',
          fieldName: 'cardInfo',
          displayName: '配件',
          placeholder: '请选择配件',
          isNull: 0
        }
      ]
      // 增加安装产品和安装位置
      this.partField.forEach((_part, _ind) => {
        fields.splice(_ind + 2, 0, _part)
      })
      // 增加产品配件选择
      if(this.isReplaceProductCard){
        fields.forEach(item=>{
          if(item.fieldName === 'number'){
            item.disabled = true
          }
        })
        fields.splice(0, 0, ...updateSparepartField)
      }
      if(this.cardInfoFilterFields?.length > 0){
        fields.push(...this.cardInfoFilterFields)
      }

      // 完成回执-添加备件 是否隐藏单价和小计
      if(!this.serviceProviderShowPrice) {
        fields = fields.filter(field => field.fieldName !== 'salePrice' && field.fieldName !== 'total')
      }

      return fields
    },
    /**
    * @description 小计
    */
    total() {
      let { number, salePrice } = this.sparepart;
      return number && salePrice ? (number * salePrice).toFixed(2) : '';
    },
    /**
    * @description 允许修改单价
    */
    allowEditPrice() {
      return this.editUnitPrice && !this.isPaySuccess;
    },
    /**
    * @description 是否开启个人备件库
    */
    personalRepertory() {
      return this.config.personalRepertory;
    },
    /**
    * @description 备件清单字段
    */
    sparepartFields() {
      let fields = this.sparepartCard?.fields || [];

      // 完成回执-添加服务项目 是否隐藏单价和小计
      if(!this.serviceProviderShowPrice) {
        fields = fields.filter(field => field.fieldName !== 'salePrice' && field.fieldName !== 'total')
      }

      return fields;
    },
    /** 
    * @description 开启出库申请
    */
    allowPartOut() {
      let config = JSON.parse(this.sparepartCard?.config || '{}');
      return config.isTaskOutRep;
    }
  },
  watch: {
    visible(n) {
      this.chooseDefaultProduct()
    }
  },
  methods: {
    getSparepartConfigValid(){
      TaskApi.getSparepartConfigValid().then(r=>{
        if(r.status == 0){
          this.isGoGet = r.data
        }
      })
    },
    goGet(){
      // this.$platform.openTab({
      //   id: 'M_VIP_SPAREPART_STOCK',
      //   title: '备件库存',
      //   close: true,
      //   url: `/partV2/repertory/stock${this?.sparepart?.name ? `?name=${this.sparepart.name}` : ''}`
      // });
      let param = {
        type: PageRoutesTypeEnum.PageSparepartStock,
      }
      if(this?.sparepart?.name) {
        param.params = `name=${this.sparepart.name}`
      }
      openAccurateTab(param)
    },
    formatCustomizeAddress(ad) {
      return formatAddress(ad)
    },
    getCardInfoColumsAll(){
      this.replaceCardInfoIds.length > 0 && getCardFieldAll({cardInfoIds:this.replaceCardInfoIds}).then(res=>{
        if(res.success){
          let filterRes = res.result.filter(item=>{
            return item.formType !== 'attachment'
          })
          this.cardInfoColumsAll = filterRes?.filter(item=>{
            return item.formType != 'relationReplacementPart' && item.fieldName != 'part'
          })

        }else{
          console.log(res.message)
        }
      })
    },
    resetSparepartInfo(){
      // 重置备件信息
      if(this.selectedSparepart.length != 0){
        this.selectedSparepart = [];
      }
      this.sparepart = this._initData();
      this.chooseDefaultProduct()
    },
    deleteItem(scope){
      if(this.isReplaceProductCard){
        let idxCardId = this.replaceCardIds.findIndex((item)=>{
          return item === this.value[scope.$index].replaceCardId
        })
        let idxCardInfoId = this.replaceCardInfoIds.findIndex((item)=>{
          return item === this.value[scope.$index].replaceCardInfoId
        })
        if(idxCardId > -1){
          this.replaceCardIds.splice(idxCardId, 1)
        }
        if(idxCardInfoId > -1){
          this.replaceCardInfoIds.splice(idxCardInfoId, 1)
          this.getCardInfoColumsAll()
        }
      }
      this.value.splice(scope.$index, 1)
    },
    /**
    * @description 选择产品
    */
    updateProduct({field, newValue, oldValue}) {
      if(newValue && this.replaceCardId){
        this.cardInfos = []
        this.cardInfoId = ''
        this.resetSparepartInfo()
        this.$nextTick(()=>{
          this.getCardInfo()
        })
      }
    },
    /**
    * @description 选择产品配件类别
    */
    updateRelationPartCard({field, newValue, oldValue}) {
      if(newValue && this.replaceProductId){
        this.cardInfos = []
        this.cardInfoId = ''
        this.resetSparepartInfo()
        this.getCardFieldAll({cardId:newValue})
      }
    },
    /**
    * @description 选择配件
    */
    updateCardInfo({field, newValue, oldValue}) {
      if(newValue){
        this.resetSparepartInfo()
        this.searchValue = this.cardInfos.find(item=>{
          return item.id === newValue
        }).searchText
      }
    },
    /**
    * @description 获取配件自定义字段
    */
    getCardFieldAll(params) {
      getCardFieldAll(params).then(res=>{
        if(res.success){
          this.cardInfoFields = res.result
          res.result.forEach(item=>{
            if(item.formType == 'select' && item.setting && item.setting.isMulti){
              this.$set(this.sparepart, item.fieldName, [])
            }
          })
          this.getCardInfo() // 在这里请求防止出现配件select中的form-view渲染不完全前被选择
        }else{
          console.log(res.message)
        }
      })
    },
    getCardInfo(){
      this.cardInfos = []
      let params = {
        productId: this.replaceProductId,
        cardId: this.replaceCardId
      }
      TaskApi.getCardInfo(params).then(res=>{
        if(res.success){
          // 选择配件后回显 回显字段为字段fieldType=‘relationReplacementPart’，setting中fieldName=‘name’的字段对应的值
          let filterFieldName, searchFieldName // 回显字段
          this.cardInfoFields.forEach(item=>{
            if(item.formType === 'relationReplacementPart' && item.setting?.fieldName === 'name'){
              filterFieldName = item.fieldName
            }
            if(item.formType === 'relationReplacementPart' && item.setting?.fieldName === 'serialNumber'){
              searchFieldName = item.fieldName
            }
          })
          let tempArr = res.result.map((item)=>{
            item.value = item.id
            item.text = item.attribute[filterFieldName]
            item.searchText = item.attribute[searchFieldName]
            return item
          })
          this.cardInfos = tempArr
        }else{
          console.log(res.message)
        }
      })
    },
    getRelationPartCard(){
      TaskApi.getRelationPartCard().then(res=>{
        if(res.success){
          this.relationPartCards = res.result.map(item=>{
            item.text = item.name
            item.value = item.id
            return item
          })
        }else{
          console.log(res.message)
        }
      })
    },
    // 根据产品id获取产品名称
    getProductName(id) {
      let name = ''
      this.products.forEach(product => {
        if (id == product.id) {
          name = product.name
        }
      })
      return name
    },
    // 只有一个产品时默认选中
    chooseDefaultProduct() {
      if (this.partField.length && this.products.length && this.products.length == 1) {
        this.installProductId = this.products[0].id
        this.$set(this.sparepart, 'installProductId', this.installProductId)
      }
    },
    /**
    * @description 初始化备件默认值
    */
    _initData() {
      let _initData = {
        id: '',
        name: '',
        serialNumber: '',
        type: '',
        standard: '',
        salePrice: '',
        costPrice: '',
        number: '',
        unit: '',
        availableNum: '',
        repertoryCount: '',
        description: '',
        repertoryName: '',
        repertoryStaffId: '',
        repertoryId: '',
        sparePartId: ''
      }
      // 安装产品和安装位置有数据时 增加这两个字段
      if (this.value && this.value.length) {
        this.value.forEach(val => {
          for (let v in val) {
            if (v == 'installProductId') {
              _initData.installProductId = ''
            } else if (v == 'installPosition') {
              _initData.installPosition = ''
            }
          }
        })
      }

      if(this.isReplaceProductCard) {
        _initData.replaceProductId = ''
        _initData.replaceCardId = ''
        _initData.cardInfoId = ''

        this.cardInfoFilterFields.forEach(item=>{
          if(item.formType == 'select' && item.setting && item.setting.isMulti){
            _initData[item.fieldName] = []
          }
        })
      }

      return _initData
    },
    /**
    * @description 修改列表备件数量
    */
    handleSparepartNum(item) {
      let maxNum = item.repertoryCount || 0;
      // 剩余可申请的备件数量
      let availableNum = item.availableNum || 0
      // 如果有自定义字段 maxNum为库存减去列表其它num
      if (this.partField.length) {
        if (!item.isAdd) {
          // 如果该备件没有做标记则做标记
          item.isAdd = true
        }
        this.value.forEach((val, ind) => {
          // id相同时说明是同一个备件 只是自定义选择的不一样
          if (item.id == val.id && val.isAdd) {
            let index = -1
            const attribute1 = item.attribute || {}
            const attribute2 = val.attribute || {}
            if (_.isEqual(attribute1, attribute2)) {
              index = ind
            }
            console.log(index, this.originValue, this.value, 'originValue 调试123')
            // originValue存在 说明是备件列表已存在的备件 库存变动为number减去originValue.number
            let num = val.number
            if (index > -1 && this.originValue[index]) num = this.originValue[index].number
            maxNum -= num
          }
        })
        maxNum < 0 ? maxNum = 0 : ''
        // 当前备件最大的库存应为库存减去所有同一个id的备件库存再加上当前备件的数量
        maxNum += item.number
      }
      let value = Number(item.number) - Number(item.oldNumberVal);
      let count = this.decimalNumber(value);
      let min = maxNum > 1 ? 1 : maxNum;

      if (item.number <= 0) {
        this.$platform.alert('请输入正确的数量');
        item.number = 1;
        return;
      }
      
      const totalNum = Number(availableNum) + Number(item.oldNumberVal)
      if (value > availableNum) {
        let warningMsg = item.spType == 0 ? `从${ item.repertoryName }仓库只出库${ totalNum }个备件，如果实际超过该用量 ，请再从备件库中添加` : `库存数量为：${ totalNum}`;
        this.$platform.alert(warningMsg);
        item.number = totalNum;
        return;
      }
      
      if (count != -1 && count == 0) {
        this.$platform.alert('请输入大于0的正整数');
        item.number = min;
        return;
      }
      
      if (count != -1 && count != 0) {
        this.$platform.alert(`请输入大于0的${ count }位小数`);
        item.number = min;
      }
    },
    /**
    * @description 修改列表备件单价
    */
    handlePrice(item) {
      let value = Number(item.salePrice);
      let count = MathUtil.decimalNumber(value);
      let oldPrice = item.oldPrice ? item.oldPrice : 0;

      if(value < 0){
        this.$platform.alert('请输入不小于0的数值');
        item.salePrice = oldPrice;
        return;
      }

      if(count > 2) {
        this.$platform.alert('最多只能输入2位小数');
        item.salePrice = oldPrice;
        return;
      }
    },
    /**
    * @description 弹窗关闭重置数据
    */
    reset() {
      this.repertoryId = this.repertoryList[0]?.value || 0;
      this.sparepart = this._initData();
      this.selectedSparepart = [];
      this.installProductId = ''

      this.replaceProductId = ''
      this.replaceCardId = ''
      this.cardInfoId = ''
      this.cardInfos = []
      this.cardInfoFields = []
      // 清空校验结果
      this.$refs.form.$children.map(child => {
        if (child.$el.className == 'form-item err') {
          child.$el.dispatchEvent(new CustomEvent('form.clear.validate', {bubbles: false}));
        }
      })
    },
    /**
    * @description 更新表单数据
    */
    update({field, newValue, oldValue}) {
      let {fieldName, displayName} = field;
      if (this.$appConfig.debug) {
        console.info(`[FormBuilder] => ${displayName}(${fieldName}) : ${JSON.stringify(newValue)}`);
      }
      this.$set(this.sparepart, fieldName, newValue);
    },
    /**
    * @description 选择仓库
    */
    updateRepertory() {
      this.resetSparepartInfo()
    },
    /**
    * @description 搜索备件
    */
    searchPart(params) {
      // params has three properties include keyword、pageSize、pageNum.
      const pms = params || {};
      pms.repertoryId = this.repertoryId || '';
      pms.with_OOS = false;
      this.isReplaceProductCard ? pms.keyWord = this.searchValue + pms.keyword : pms.keyWord = pms.keyword;
      objectDateToTimestamp(pms, ['timeEnd', 'timeStart'])
      return this.$http
        .post('/task/spare/list', pms)
        .then(res => {
          if (!res || !res.list) return;  
          let isFreeSparePartFee = JSON.parse(sessionStorage.getItem('isFreeSparePartFee')); 
          if (isFreeSparePartFee) {
            res.list.forEach(item => {
              item.salePrice = 0;
            })
          }   
          res.list = res.list.map(template =>
            Object.freeze({
              label: template.name,
              value: template.id,
              ...template
            })
          )  
          return res;
        })
        .catch(e => console.error(e));
    },
    /**
    * @description 选择备件
    */
    updatePart(value) {
      let newValue = value[0];

      for (let key in this.sparepart) {
        if (key == 'salePrice') {
          this.sparepart.salePrice = newValue.salePrice.toFixed(2);
        } else if (key == 'number') {
          this.sparepart.number = newValue.availableNum > 1 ? 1 : newValue.availableNum;
        } else {
          this.sparepart[key] = newValue[key];
        }
      }
      this.cardInfoFilterFields.forEach(item=>{
        if(item.formType == 'select' && item.setting && item.setting.isMulti){
          this.$set(this.sparepart, item.fieldName, [])
        }
      })
      this.chooseDefaultProduct()
    },
    /**
    * @description 数量校验
    */
    validateNumber(value, field) {
      let maxNum = this.sparepart.availableNum || 0;
      // 如果有自定义字段 maxNum为库存减去列表其它num
      if (this.partField.length) {
        maxNum = this.sparepart.repertoryCount || 0;
        this.value.forEach((val, ind) => {
          // id相同时说明是同一个备件 只是自定义选择的不一样
          if (this.sparepart.id == val.id && val.isAdd) {
            let index = -1
            const attribute1 = this.sparepart.attribute || {}
            const attribute2 = val.attribute || {}
            if (_.isEqual(attribute1, attribute2)) {
              index = ind
            }
            console.log(index, this.originValue, this.value, 'originValue 调试123')
            // originValue存在 说明是备件列表已存在的备件 库存变动为number减去originValue.number
            let num = val.number
            if (index > -1 && this.originValue[index]) num = val.number - this.originValue[index].number
            maxNum -= num
          }
        })
        maxNum < 0 ? maxNum = 0 : ''
      }
      const val = Number(value);
      let count = this.decimalNumber(val);

      return new Promise((resolve, reject) => {
        if (val <= 0) {
          return resolve('请输入正确的数量');
        } else if(val > maxNum){
          return resolve('库存不足，请输入正确的数量');
        } else if (count != -1 && count == 0) {
          return resolve('请输入大于0的正整数');
        } else if (count != -1 && count != 0) {
          return resolve(`请填写大于0的${ count }位小数`);
        }

        resolve(null);
      })
    },
    /**
    * @description 数量小数位
    */
    decimalNumber(num) {
      let { sparepart2, precision } = this.config;
      let count = MathUtil.decimalNumber(num);

      if(!sparepart2 && count != 0) return 0;
      if(precision >= count) return -1;
      return precision;
    },
    compare(){
      let idxCardId = this.replaceCardIds.findIndex(item => item == this.replaceCardId);
      let idxCardInfoId = this.replaceCardInfoIds.findIndex(item => item == this.cardInfoId);
      if(idxCardId > -1 && idxCardInfoId > -1){
        return true
      }
      return false
    },
    /**
    * @description 添加备件
    */
    async submit() {
      try {
        const validateRes = await this.$refs.form.validate();
        if (!validateRes) return;

        let sparepartObj = JSON.parse(JSON.stringify(this.sparepart));
        sparepartObj.oldPrice = sparepartObj.salePrice;
        // 添加一个标识，代码该备件数据是用户新添加的，而不是旧数据回显的
        sparepartObj.userAddData = true

        let newValue = this.value;

        // 查找已添加的备件中是否存在该备件
        let ids = ''
        if (this.partField.length) {
          // 如果有自定义字段 安装产品和安装位置 还需要判断安装产品和安装位置是否相等
          sparepartObj.attribute = {
            installPosition: this.sparepart.installPosition,
            installProductId: this.sparepart.installProductId
          }
          // 加入进来的新增isAdd字段 避免编辑回执时计算备件availableNum出错
          sparepartObj.isAdd = true
          ids = newValue.findIndex(val => val.id == sparepartObj.id && val.salePrice == sparepartObj.salePrice && _.isEqual(val.attribute, sparepartObj.attribute));
          
        } else {
          ids = newValue.findIndex(val => val.id == sparepartObj.id && val.salePrice == sparepartObj.salePrice);
        }
        // 选择配件后传入的参数
        if(this.isReplaceProductCard){
          // 判断是否已替换过当前配件
          if(this.compare()){
            this.$message.warning('请勿重复添加当前配件')
            return
          }
          this.replaceCardInfoIds.push(this.cardInfoId)
          // 当更换配件记录中已存在 配件类别和配件时对比使用
          this.replaceCardIds.push(this.replaceCardId)
          this.getCardInfoColumsAll()

          // 表格列自定义字段显示
          this.cardInfoColums = this.cardInfoFilterFields
          sparepartObj.replaceProductId = this.replaceProductId
          sparepartObj.replaceCardId = this.replaceCardId
          sparepartObj.replaceCardInfoId = this.cardInfoId // 这里传的是配件的id不是配件类目的id
          let tempObj = {}
          this.cardInfoFilterFields.forEach(item=>{
            tempObj[item.fieldName] = this.sparepart[item.fieldName]
          })
          sparepartObj.cardInfoAttribute = tempObj
        }
        // 目前如果是ssb添加同样的备件用量不增加，单独增加一列数据
        if (ids > -1 && !this.isReplaceProductCard) {
          const sum = Number(math.add(math.bignumber(newValue[ids].number), math.bignumber(sparepartObj.number)));
          newValue[ids].number = sum > sparepartObj.availableNum ? sparepartObj.availableNum : sum;

          if (this.partField.length) {
            newValue[ids].number = sum
          }
        } else {
          newValue.push(sparepartObj);
        }

        this.$emit('update', {field: this.field, newValue});

        this.visible = false;

      } catch (e) {
        console.error('err', e);
      }
    },
    setEditConfig(config) {
      let { editUnitPrice, isPaySuccess, sparepartList, sparepartCard } = config || {};

      this.editUnitPrice = editUnitPrice;
      this.isPaySuccess = isPaySuccess;
      this.sparepartCard = sparepartCard;
      this.sparepartList = sparepartList;
    },
    showPartWindow() {
      if (!this.visible) {
        return this.visible = true
      }

      this.flickerWindow = true
      this.$nextTick(() => {
        this.flickerWindow = false
      })
    },
    cancelWindow() {
      this.visible = false
      this.flickerWindow = false
    },
    /**
    * @description 打开备件清单弹窗
    */
    openPartListDialog() {
      this.$refs.sparepartListDialog.open();
    },
    /**
    * @description 设置仓库默认值
    */
    setRepertoryId() {
      this.repertoryId = this.repertoryList[0]?.value || 0;
    },
    /**
    * @description 当前租户备件配置
    */
    getSparepartConfig() {
      return TaskApi.getSparepartConfig().then(async res => {
        this.config = res || {};

        let { sparepart2, personalRepertory } = this.config;

        // 备件1.0不显示仓库
        if (!sparepart2) {
          this.showRepertory = false;
          return this.setRepertoryId();
        }

        // 开启个人备件库
        if (personalRepertory) {
          this.repertoryList = [{
            text: '个人备件库',
            value: 0
          }];

          return this.setRepertoryId();
        }

        this.repertoryList = [];

        // 获取当前用户可用仓库列表
        const list = await TaskApi.getRepertoryList();
        if (!list?.length) {
          return this.setRepertoryId();
        }

        this.repertoryList = list.map(item => {
          return Object.freeze({
            text: item.name,
            value: item.id
          })
        })

        this.setRepertoryId();

      }).catch(err => console.error(err))
    }
  },
  async mounted() {
    this.$eventBus.$on('task_receipt_update_config', this.setEditConfig);
    this.$eventBus.$on('task_receipt_update_sparepart_config', this.getSparepartConfig);
    this.isFreeSparePartFee = JSON.parse(sessionStorage.getItem('isFreeSparePartFee'));
    
    try {
      await this.getSparepartConfigValid()
      // 获取当前租户备件库配置信息
      await this.getSparepartConfig();
      
      // 获取是否有安装产品和安装位置 目前只有博立有数据 其它的数据为空
      const result = await TaskApi.getExpensePartField()
      if (result.code == 0) {
        result.result.forEach((res, ind) => {
          if (res.fieldName == 'installProductId') {
            // 设置安装产品的下拉数据
            let _res = Object.assign({}, res)
            let products = this.products
            products.forEach(product => {
              product.text = product.name
              product.value = product.id
            })
            _res.setting = {
              isMulti: false,
              dataSource: products
            }
            result.result.splice(ind, 1, _res)
          } else if (res.fieldName == 'installPosition') {
            // 设置安装位置的下拉数据
            let dataSource = res.setting.dataSource
            let _res = Object.assign({}, res)
            _res.setting = {
              isMulti: res.setting.isMulti,
              dataSource: []
            }
            dataSource.forEach(s => {
              _res.setting.dataSource.push({
                text: s,
                value: s
              })
            })
            result.result.splice(ind, 1, _res)
          }
        })
        this.partField = result.result || []
        if (this.value && this.value.length) {
          this.originValue = _.cloneDeep(this.value)
          console.log(this.originValue, 'originValue断点')
        }
      }

      if(this.isReplaceProductCard){
        this.replaceCardInfoIds = []
        this.value.forEach(item => {
          item.replaceCardInfoId && this.replaceCardInfoIds.push(item.replaceCardInfoId)
          item.replaceCardId && this.replaceCardIds.push(item.replaceCardId)
        })
        this.getCardInfoColumsAll()
      }
    } catch (err) {
      console.error('err', err);
    }
    this.getRelationPartCard()
  },
  beforeDestroy() {
    this.$eventBus.$off('task_receipt_update_config', this.setEditConfig);
    this.$eventBus.$off('task_receipt_update_sparepart_config', this.getSparepartConfig);
  },
  components: {
    [SparepartListDialog.name]: SparepartListDialog
  }
}
</script>

<style lang="scss">
.form-sparepart-modal {
  z-index: 990 !important; // 选择地址被遮盖降低层级
}
.form-item.err :not(.is-success){
  .form-item :not(.err) {
    input, textarea, .base-select-main-content {
      border-color: #e0e1e2 !important;
    }
  }

  .form-item.err {
    input, .base-select-main-content {
      border-color: #f56c6c !important;
    }
  }
}

.form-sparepart{
  text-align: left;

  .btn-group {
    padding: 0 !important;

    .el-button {
      min-width: auto !important;
      padding: 8px 0 0 0;
    }
  }

  .el-table {
    margin: 10px 0;

    .sparepart-number-input {
      width: 99%;
    }

    .el-icon-delete {
      font-size: 16px;
      color: $color-danger;
      font-weight: 700;
    }
  }
}

.sparepart-template-option {
  * {
    margin: 0;
  }
  padding: 10px 0;
  h3 {
    font-size: 14px;
    font-weight: 500;
    line-height: 24px;
  }

  p {
    display: flex;
    justify-content: space-between;
    line-height: 24px;

    & > span {
      width: 25%;
      display: flex;
      justify-content: flex-start;
      font-size: 12px;
      color: #666666;
      padding-right: 10px;

      & > label {
        flex-shrink: 0;
        padding: 0;
        width: 40px !important;
      }
      & > span {
        flex-grow: 1;
        @include text-ellipsis();
      }
    }
  }
  .sparepart-addition-info {
    & > span {
      width: 50%;
      .addition-product-type {
        width: auto !important;
      }
    }
  }
}
.free-sparepart-fee {
  .iconfont {
    color: #FAAD14;
    margin-right: 8px;
  }
}
.goget-box{
  position: relative;
}
.goget{
  position: absolute;
    right: 35px;
    top: 0;
    line-height: 32px;
    cursor: pointer;
    color: $color-primary-light-6;
}
</style>
<style lang="scss" scoped>
.update-sparepart-title {
  margin-left: 20px;
  color: $color-primary-light-6;
}
.update-sparepart-mess {
  margin: 8px 0px 18px 8px;
  color: $color-primary-light-6;
}
</style>